<template>
	<div>
		<el-card class="box-card" shadow="always" :body-style="{ padding: '20px' }">
			<!-- 三级分类列表 -->
			<CategorySelector :disabled="!isShowList" />
		</el-card>
		<el-card
			class="box-card"
			:body-style="{ padding: '20px' }"
			:style="{ marginTop: '30px' }"
		>
			<template #header v-if="isShowList">
				<el-button type="primary" size="default" @click="addAttr" :disabled="!category3Id">新增属性</el-button>
			</template>

			<!-- 商品属性列表 -->
			<el-table border stripe :data="attrList" v-if="isShowList">
				<el-table-column type="index" width="60" align="center" label="序号" />
				<el-table-column label="属性名称" align="center" prop="attrName" />
				<el-table-column
					label="属性名称列表"
					align="center"
					prop="attrValueList"
				>
					<template v-slot="{ row }">
						<el-tag
							effect="plain"
							v-for="item in row.attrValueList"
							:key="item.id"
						>
							{{ item.valueName }}
						</el-tag>
					</template>
				</el-table-column>
				<el-table-column label="操作" align="center">
					<template v-slot="{ row }">
						<el-button
							type="warning"
							icon="ele-Edit"
							title="修改属性"
							@click="updateAttr(row)"
						></el-button>
						<el-button
							type="danger"
							icon="ele-Delete"
							title="删除属性"
							@click="deleteAttr(row)"
						></el-button>
					</template>
				</el-table-column>
			</el-table>

			<div v-else>
				<el-form label-width="80px" :inline="true">
					<el-form-item label="属性名">
						<el-input placeholder="请输入属性名" v-model="newAttrData.attrName" />
					</el-form-item>
					<div style="margin-top: 20px">
						<el-button type="primary" size="default" @click="addAttrValue">添加属性值</el-button>
						<el-button plain size="default" @click="cancel">取消</el-button>
					</div>
				</el-form>

				<el-table
					:data="newAttrData.attrValueList"
					border
					stripe
					:style="{ marginTop: '30px' }"
				>
					<el-table-column type="index" width="80" label="序号" />
					<el-table-column label="属性值名称" prop="valueName">
						<template v-slot="{ row, $index }">

							<el-input
								ref="inp"
								placeholder="请输入新增的属性值名称"
								v-model="row.valueName"
								v-if="row.isEdit"
								@blur="toLook(row, $index)"
							></el-input>
							<!-- 
								编辑模式和查看模式
								点击修改时 是查看模式 加载span标签   点击新增时 是编辑模式 加载input
								用新增属性 row里的 isEdit 控制
							 -->
							<span v-else @click="toEdit(row)">{{ row.valueName }}</span>

						</template>
					</el-table-column>
					<el-table-column label="操作">
						<template v-slot="{ $index }">
							<!-- 气泡确认框 -->
							<el-popconfirm
								title="是否删除属性?"
								@confirm="deleteAttrValue"
							>
								<template #reference>
									<el-button
										type="danger"
										size="small"
										icon="ele-Delete"
									></el-button>
								</template>
							</el-popconfirm>
						</template>
					</el-table-column>
				</el-table>
				<div style="margin-top: 30px">
					<el-button
						type="primary"
						@click="saveAttr"
						>保存</el-button
					>
					<el-button type="default" @click="cancel">取消</el-button>
				</div>
			</div>
		</el-card>
	</div>
</template>

<script setup lang="ts">
// 引入操作属性的接口和类型
import {
	reqAttrList,
	reqDeleteAttr,
	reqUpdateAddAttr,
	type AttrListItemType,
	type AttrValueListType,
	type AttrListType,
} from "@/api/attr";
import { nextTick, onMounted, ref, watch } from "vue";

// 引入store对象
import { useCategoryStore } from "@/stores/category";
import { storeToRefs } from "pinia";
import { ElMessage } from "element-plus";

// 引入深拷贝函数
import { cloneDeep } from "lodash";

const CategoryStore = useCategoryStore();
// 对state里的数据进行解构
const { category1Id, category2Id, category3Id } = storeToRefs(CategoryStore);

// 逻辑1 获取属性列表
const attrList = ref<AttrListType>([]);

// 封装获取属性列表的方法
const getAttrList = async () => {
	const res = await reqAttrList(
		category1Id.value as number,
		category2Id.value as number,
		category3Id.value as number
	);
	attrList.value = res;
};

// 初始化 获取商品属性 可以直接用watch监听 不用初始化
// onMounted(()=>{
// 	if( category3Id.value === null ) return
// 	getAttrList()
// })

// 监听三级分类参数 如果发生改变 重新发请求
watch(
	category3Id,
	newVal => {
		if (!newVal) {
			// 如果三级列表变为null 则把属性列表变为空
			attrList.value = [];
			return;
		}
		getAttrList();
	},
	{
		immediate: true,
	}
);

// 商品属性默认显示 (和添加弹窗相适应)
const isShowList = ref(true);

// 添加商品属性逻辑
// 定义新增属性的初始值
const newAttrData = ref< AttrListItemType>({
	attrName:'',
	categoryId:category3Id.value as number,
	categoryLevel : 3, //选中的3级id的级别 1 2 3
	attrValueList:[]  //表格的数据
})

// 添加逻辑: 分别收集attrName  attrValueList
// 点击添加按钮
const addAttr = ()=>{
	isShowList.value = false // 显示新增表单
	// 每次新增时, 清空新增的内容
	newAttrData.value = {
		attrName:'',
		categoryId:category3Id.value as number,
		categoryLevel : 3, //选中的3级id的级别 1 2 3
		attrValueList:[]  //表格的数据
	}
}

// 添加逻辑
const addAttrValue = ()=> {
	newAttrData.value.attrValueList.push({
		valueName: '',
		attrId: newAttrData.value.id,
		isEdit: true//  新增一个属性  代表当前是编辑模式或查看模式
	})

	// 添加属性值 也需要自动聚集
	nextTick(()=>{
		inp.value?.focus() // 自动聚焦
	})


}

// 点击修改 事件
/* 
这里修改 需要把原来的row的值放到newAttr里  注意 要用深拷贝 把row的值拷贝到newAttr里面
原因:
	1. newAttr 里面还有一个数组
	2. 如果是浅拷贝 改变一个就会改变row的值
方法: lodash  引入时 解构
*/
const updateAttr = async(row:AttrListItemType) => {
	isShowList.value = false
	
	newAttrData.value = cloneDeep(row) // 回填数据
	// 回填数据之后,我们给每一个属性值对象添加一个isEdit属性,代表当前属性值是编辑模式还是查看模式
	newAttrData.value.attrValueList.forEach(item => item.isEdit = false)
}

// 点击 input  去查看模式
const toLook = (row:AttrValueListType, index: number) => {
	// 判断当前row是不是空 如果为空 直接移出
	if(row.valueName === '') newAttrData.value.attrValueList.splice(index,1)
	// 查看所有的属性中 是否 有和当前属性相同的  如果有把当前的移除
	const res = newAttrData.value.attrValueList.some(item => {
		// 遍历时 除自身外的
		if(item !== row) {
			return item.valueName === row.valueName
		}
	})
	// 如果有重复的 去除当前数据
	if(res) newAttrData.value.attrValueList.splice(index,1)
	row.isEdit = false
}

// 点击span  去编辑模式 
// 获取span标签 通过ref属性
const inp = ref<HTMLInputElement>()
const toEdit = (row:AttrValueListType) => {
	row.isEdit = true

	// 点击span时 需要自动聚焦 一共有两个地方需要自动聚焦  还有添加属性值时
	nextTick(()=>{
		inp.value?.focus() // 自动聚焦
	})
}

// 保存回调函数  确定是新增还是修改
const saveAttr = async() =>{

	// 属性值为空 不能新增或修改 直接return
	if (newAttrData.value.attrValueList.length <= 0) {
    ElMessage.error("属性值列表不能为空");
    return;
  }

	try {
		await reqUpdateAddAttr(newAttrData.value)
		ElMessage.success('新增或修改成功')
		isShowList.value = true
		getAttrList() // 重新发起请求
	} catch (e) {
		ElMessage.error('新增或修改失败')
	}
}

// 删除属性名逻辑
const deleteAttr = async (row:AttrListItemType ) => {
	// 发送删除请求
	try {
		await reqDeleteAttr(row.id as number)
		ElMessage.success("删除属性成功");
    //重新发送请求
    getAttrList();
	} catch (e) {
		ElMessage.error("删除属性失败");
	}
}


// 删除属性值逻辑 
const deleteAttrValue = ($index:number) => {
	newAttrData.value.attrValueList.splice($index,1)
}


// 点击取消事件
const cancel = () => {
	isShowList.value = true 
}

</script>

<style scoped></style>
